#ifndef GENERIC_LIST_H
#define GENERIC_LIST_H

typedef struct _list_entry {
  void *head;
  struct _list_entry *tail;
} list_entry_t;

typedef struct _generic_list {
  // Ouch we should not be doing this plzthx
  type_t type;
  list_entry_t *first;
  list_entry_t *last;
  unsigned int length;
} generic_list_t;

typedef struct _iterator
{
  list_entry_t *first;
  list_entry_t *current;
  list_entry_t *last;
} iterator_t;

iterator_t *get_iterator(generic_list_t *list);
void *new_iterate_first(iterator_t *iterator, generic_list_t *list);
void *iterate_first(iterator_t *iterator);
void *iterate_next(iterator_t *iterator);
int iterate_is_valid(iterator_t *iterator);
int iterate_at_end(iterator_t *iterator);

generic_list_t *make_generic_list(void *head);
void generic_list_add(generic_list_t *list, void *value);
void *generic_list_remove(generic_list_t *list);
void *generic_list_index(generic_list_t *list, int n);
generic_list_t *splice_generic_list(list_entry_t *pivot);
generic_list_t *generic_list_append(generic_list_t *a, generic_list_t *b);
generic_list_t *generic_list_copy(generic_list_t *list);

#endif // GENERIC_LIST_H
